package com.tian.service.impl.management;


import com.tian.common.enums.OptTypeEnum;
import com.tian.common.util.AdminUserCacheUtil;
import com.tian.common.util.Result;
import com.tian.common.util.UserCacheUtil;
import com.tian.dto.management.req.MenuReqDto;
import com.tian.dto.management.resp.Menu4AuthorRespDto;
import com.tian.dto.management.resp.MenuRespDto;
import com.tian.dto.management.resp.PageDto;
import com.tian.dto.management.resp.UserInfoRespDto;
import com.tian.dto.user.ChargeUserLoginResDto;
import com.tian.entity.Menu;
import com.tian.entity.RoleMenu;
import com.tian.mapper.MenuMapper;
import com.tian.mapper.RoleMenuMapper;
import com.tian.service.management.MenuService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * {@code @description:} TODO
 *
 * @author tianwc 公众号：Java后端技术全栈
 * 在线刷题 1200+java面试题和1000+篇技术文章：<a href="https://woaijava.cc/">博客地址</a>
 * {@code @date:} 2024-09-09 22:49
 * {@code @version:} 1.0
 */
@Slf4j
@Service
public class MenuServiceImpl implements MenuService {


    @Resource
    private RoleMenuMapper roleMenuMapper;
    @Resource
    private MenuMapper menuMapper;

    @Override
    public Result<List<MenuRespDto>> allMenu() {
        UserInfoRespDto user = AdminUserCacheUtil.getUser();
        List<Menu> menus;
        if (user.getRoleId() == 1) {
            menus = menuMapper.selectByParentId();
        } else {
            menus = menuMapper.selectByRoleId(user.getRoleId());
        }
        List<MenuRespDto> mainMenuList = new ArrayList<>();
        //一级菜单
        for (Menu menu : menus) {
            List<Menu> children = menuMapper.selectListByParentId(menu.getId());
            MenuRespDto menuRespDto = new MenuRespDto();
            BeanUtils.copyProperties(menu, menuRespDto);
            List<MenuRespDto> childrenMenuRespDtoList = new ArrayList<>();
            if (!CollectionUtils.isEmpty(children)) {
                //二级菜单
                for (Menu child : children) {
                    MenuRespDto childMenuRespDto = new MenuRespDto();
                    BeanUtils.copyProperties(child, childMenuRespDto);
                    childrenMenuRespDtoList.add(childMenuRespDto);
                }
                menuRespDto.setChildren(childrenMenuRespDtoList);
            }
            mainMenuList.add(menuRespDto);
        }
        return Result.success(mainMenuList);
    }

    @Override
    public Result<List<Menu4AuthorRespDto>> allMenu4Author() {
        List<Menu> menus = menuMapper.selectByParentId();
        List<Menu4AuthorRespDto> mainMenuList = new ArrayList<>();
        for (Menu menu : menus) {
            List<Menu> children = menuMapper.selectListByParentId(menu.getId());
            Menu4AuthorRespDto menu4AuthorRespDto = new Menu4AuthorRespDto();
            menu4AuthorRespDto.setValue(menu.getId());
            menu4AuthorRespDto.setLabel(menu.getMenuName());
            List<Menu4AuthorRespDto> childrenMenuRespDtoList = new ArrayList<>();
            if (!CollectionUtils.isEmpty(children)) {
                //二级菜单
                for (Menu child : children) {
                    Menu4AuthorRespDto childMenuRespDto = new Menu4AuthorRespDto();
                    childMenuRespDto.setValue(menu.getId());
                    childMenuRespDto.setLabel(menu.getMenuName());
                    childrenMenuRespDtoList.add(childMenuRespDto);
                }
                menu4AuthorRespDto.setChildren(childrenMenuRespDtoList);
            }
            mainMenuList.add(menu4AuthorRespDto);
        }
        return Result.success(mainMenuList);
    }

    @Override
    public Result<List<Integer>> userAllMenu4Author(Integer roleId) {
        List<RoleMenu> roleMenus =  roleMenuMapper.selectByRoleId(roleId);
        List<Integer> menuIdList = roleMenus.stream()
                .map(RoleMenu::getMenuId)
                .collect(Collectors.toList());
        List<Menu> menus=menuMapper.selectByMenuIds(menuIdList);
        List<Integer> mainMenuList = new ArrayList<>();
        //一级菜单
        for (Menu menu : menus) {
            mainMenuList.add(menu.getId());
        }
        return Result.success(mainMenuList);
    }

    @Override
    public Result<List<MenuRespDto>> allFirstMenu() {
        UserInfoRespDto user = AdminUserCacheUtil.getUser();
        List<Menu> menus;
        if (user.getRoleId() == 1) {
            menus = menuMapper.selectByParentId();
        } else {
            menus = menuMapper.selectByRoleId(user.getRoleId());
        }
        List<MenuRespDto> mainMenuList = new ArrayList<>();
        for (Menu menu : menus) {
            MenuRespDto menuRespDto = new MenuRespDto();
            BeanUtils.copyProperties(menu, menuRespDto);
            mainMenuList.add(menuRespDto);
        }
        MenuRespDto menuRespDtoMain = new MenuRespDto();
        menuRespDtoMain.setMenuName("主菜单");
        menuRespDtoMain.setId(0);
        menuRespDtoMain.setParentId(0);
        mainMenuList.add(menuRespDtoMain);
        return Result.success(mainMenuList);
    }

    @Override
    public Result<PageDto<List<MenuRespDto>>> query(MenuReqDto menuReqDto) {
        List<Menu> menus = menuMapper.selectByParentId();
        PageDto<List<MenuRespDto>> pageDto = new PageDto<>();
        List<MenuRespDto> mainMenuList = new ArrayList<>();
        int count = menus.size();
        //一技
        for (Menu menu : menus) {
            List<Menu> children = menuMapper.selectListByParentId(menu.getId());
            MenuRespDto menuRespDto = new MenuRespDto();
            BeanUtils.copyProperties(menu, menuRespDto);
            menuRespDto.setParentId(menu.getParentId());
            menuRespDto.setParentName("主菜单");
            mainMenuList.add(menuRespDto);

            if (!CollectionUtils.isEmpty(children)) {
                for (Menu child : children) {
                    MenuRespDto childMenuRespDto = new MenuRespDto();
                    BeanUtils.copyProperties(child, childMenuRespDto);
                    childMenuRespDto.setParentId(menu.getId());
                    childMenuRespDto.setParentName(menu.getMenuName());
                    mainMenuList.add(childMenuRespDto);
                    count++;
                }
            }
        }
        pageDto.setData(mainMenuList);
        pageDto.setTotalCount(count);
        return Result.success(pageDto);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<Boolean> add(MenuReqDto menuReqDto) {
        if (!menuReqDto.getOptList().isEmpty()) {
            for (Integer optType : menuReqDto.getOptList()) {
                Menu menu = new Menu();
                BeanUtils.copyProperties(menuReqDto, menu);
                menu.setOptType(optType);
                menuMapper.insert(menu);
            }
        }
        return Result.success(Boolean.TRUE);
    }

    @Override
    public Result<List<MenuRespDto>> queryShouquan() {
        List<Menu> menus = menuMapper.selectByParentId();
        List<MenuRespDto> mainMenuList = new ArrayList<>();
        //一级菜单
        for (Menu menu : menus) {
            List<Menu> children = menuMapper.selectListByParentId(menu.getId());
            MenuRespDto menuRespDto = new MenuRespDto();
            BeanUtils.copyProperties(menu, menuRespDto);
            List<MenuRespDto> childrenMenuRespDtoList = new ArrayList<>();
            if (!CollectionUtils.isEmpty(children)) {
                //二级菜单
                for (Menu child : children) {
                    MenuRespDto childMenuRespDto = new MenuRespDto();
                    BeanUtils.copyProperties(child, childMenuRespDto);
                    childMenuRespDto.setMenuName(child.getMenuName() + "-" + OptTypeEnum.getMessage(child.getOptType()));
                    childrenMenuRespDtoList.add(childMenuRespDto);
                }
                menuRespDto.setChildren(childrenMenuRespDtoList);
            }
            mainMenuList.add(menuRespDto);
        }
        return Result.success(mainMenuList);
    }
}
